/**
 * This file is Copyright © 2008 Software Craftsmen Limited. All Rights Reserved.
 */
package com.softwarecraftsmen.collections.tuples;

import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;

// Also Octuple, Nonuple, Decuple, Undecuple, Duodecuple

public class Septuple<A, B, C, D, E, F, G> extends AbstractTuple
{
	@NotNull
	public final A a;
	@NotNull
	public final B b;
	@NotNull
	public final C c;
	@NotNull
	public final D d;
	@NotNull
	public final E e;
	@NotNull
	public final F f;
	@NotNull
	public final G g;

	private Septuple(final @NotNull A a, final @NotNull B b, final @NotNull C c, final @NotNull D d, final @NotNull E e, final @NotNull F f, final @NotNull G g)
	{
		super();
		this.a = a;
		this.b = b;
		this.c = c;
		this.d = d;
		this.e = e;
		this.f = f;
		this.g = g;
	}

	@NotNull
	public static <A, B, C, D, E, F, G> Septuple<A, B, C, D, E, F, G> septuple(@NotNull final A a, @NotNull final B b, final @NotNull C c, final @NotNull D d, final @NotNull E e, final @NotNull F f, final @NotNull G g)
	{
		return new Septuple<A, B, C, D, E, F, G>(a, b, c, d, e, f, g);
	}

	@NotNull
	public Object valueAt(final Integer index)
	{
		guardValueAt(index);
		switch (index)
		{
			case 0:
				return a;
			case 1:
				return b;
			case 2:
				return c;
			case 3:
				return d;
			case 4:
				return e;
			case 5:
				return f;
			case 6:
				return g;
			default:
				throw new IllegalStateException();
		}
	}

	@NotNull
	public ArrayList<Object> toLegacyArrayList()
	{
		return (ArrayList<Object>) addToList(super.toLegacyArrayList());
	}

	@NotNull
	public LinkedList<Object> toLegacyLinkedList()
	{
		return (LinkedList<Object>) addToList(super.toLegacyLinkedList());
	}

	private List<Object> addToList(final List<Object> list)
	{
		list.add(a);
		list.add(b);
		list.add(c);
		list.add(d);
		list.add(e);
		list.add(f);
		list.add(g);
		return list;
	}

	public int size()
	{
		return 7;
	}

	@NotNull
	public String toString()
	{
		return String.format(Locale.UK, "(%1$s, %2$s, %3$s, %4$s, %5$s, %6$s, %7$s)", a, b, c, d, e, f, g);
	}

	public boolean equals(final Object o)
	{
		if (this == o)
		{
			return true;
		}
		if (o == null || getClass() != o.getClass())
		{
			return false;
		}

		final Septuple septuple = (Septuple) o;

		if (!a.equals(septuple.a))
		{
			return false;
		}
		if (!b.equals(septuple.b))
		{
			return false;
		}
		if (!c.equals(septuple.c))
		{
			return false;
		}
		if (!d.equals(septuple.d))
		{
			return false;
		}
		if (!e.equals(septuple.e))
		{
			return false;
		}
		if (!f.equals(septuple.f))
		{
			return false;
		}
		if (!g.equals(septuple.g))
		{
			return false;
		}

		return true;
	}

	public int hashCode()
	{
		int result;
		result = a.hashCode();
		result = 31 * result + b.hashCode();
		result = 31 * result + c.hashCode();
		result = 31 * result + d.hashCode();
		result = 31 * result + e.hashCode();
		result = 31 * result + f.hashCode();
		result = 31 * result + g.hashCode();
		return result;
	}

	@NotNull
	public Sextuple<A, B, C, D, E, F> slice()
	{
		return tuple(a, b, c, d, e, f);
	}
}
